#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H

#include <Windows.h>
#include <vector>
#include <map>
#include <string>
#include <cassert>
#include <gl/GL.h>

#include <IL/il.h>
#include <IL/ilu.h>
#include <IL/ilut.h>

#include "handlemanager.h"

using namespace std;



struct tagTexture  {};
typedef cHandle<tagTexture> HTexture;

//////////////////////////////////////////////////////////////////////////
// helper functions

HTexture GetTexture(const char* name);
void BindTexture(HTexture);
void ReleaseTexture(HTexture htex);
GLuint DereferenceTexture(HTexture htex);



//////////////////////////////////////////////////////////////////////////
// singleton texture manager class
// uses handles to manage textures
class cTextureManager
{
private:
	
	struct Texture
	{
		string name;
		GLuint id;
	};

	typedef cHandleManager<Texture,HTexture> HTextureMgr;
	typedef map<string,HTexture> NameIndex;
	typedef pair<NameIndex::iterator,bool> NameIndexInsertRecord;

	
	NameIndex				m_NameIndex;		// keeps the handles, indexed with the texture filenames
	HTextureMgr				m_textures;			// keeps the actual texture pointers	
	static cTextureManager* m_pInstanceSingleton;
	
	cTextureManager(void);
	~cTextureManager(void);


public:

	static cTextureManager* GetInstance();
	static void DeleteInstance();

	bool InitDevIL();

	/*
	 *	texture management
	 */
	HTexture GetTexture( const char* name );
	//void DeleteTexture(HTexture texture);
	void ReleaseTexture(HTexture texture);
	bool LoadTexture(Texture* ptex);
	bool LoadCube(Texture* ptex,char* filenames[6],bool bCompression);
	HTexture GetCube(char* names[6], bool bCompression);
	void DeleteAllTextures();
	

	/*
	 *	texture query
	 */
	const string& GetName(HTexture htex) const
	{	return (m_textures.Dereference(htex)->name);		}
	GLuint DereferenceTexture(HTexture htex) const
	{	
		const Texture* ptex = (Texture*)m_textures.Dereference(htex);
		if(ptex)
			return ptex->id;
		else
			return 0;
	}
	
	//
	// check if texture is already loaded
	bool TextureIsLoaded(const char* name)
	{	
		if(m_NameIndex.find(name)!=m_NameIndex.end())
			return true;
		return false;
	}
};







#endif


